package main

import (
	"context"
	"encoding/json"
	"fmt"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
	"net/http"
	"strconv"
)

func getlink() *kubernetes.Clientset {
	config, err := clientcmd.BuildConfigFromFlags("", "/opt/config")
	if err != nil {
		panic(err.Error())
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}
	var test = clientset
	return test
}

func getsvcinfo(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	fmt.Println("NameSpace:", r.Form["namespace"])
	w.Header().Set("Access-Control-Allow-Origin", "*")
	nss := r.Form["namespace"]
	fmt.Println("Name:", r.Form["name"])
	names := r.Form["name"]
	podl, err := getlink().CoreV1().Services(nss[0]).Get(context.Background(), names[0], metav1.GetOptions{})
	if err != nil {
		panic(err.Error())
	}
	b, err := json.Marshal(podl)
	if err != nil {
		panic(err.Error())
	}
	s := string(b)
	fmt.Fprint(w, s)
}

func createpod(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	name := r.Form["podname"]
	labels := r.Form["labels"]
	image := r.Form["image"]
	ports := r.Form["port"]
	policy := r.Form["policy"]
	namespace := r.Form["namespace"]
	in, err := strconv.ParseInt(ports[0], 10, 32)
	pod := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name: name[0],
			Labels: map[string]string{
				"app": labels[0],
			},
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  name[0],
					Image: image[0],
					Ports: []corev1.ContainerPort{
						{
							ContainerPort: int32(in),
						},
					},
					ImagePullPolicy: v1.PullPolicy(policy[0]),
				},
			},
		},
	}
	podc, err := getlink().CoreV1().Pods(namespace[0]).Create(context.Background(), pod, metav1.CreateOptions{})
	if err != nil {
		fmt.Fprint(w, err)
		panic(err.Error())
	} else {

		fmt.Fprintf(w, "pod create success：%q \n", podc.GetObjectMeta().GetName())
		fmt.Printf("pod create success：%q \n", podc.GetObjectMeta().GetName())
	}

}

func createsvc(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	name := r.Form["name"]
	ports := r.Form["port"]
	in, err := strconv.ParseInt(ports[0], 10, 32)
	if err != nil {
		panic(err)
	}
	ports2 := r.Form["port2"]
	in2, err := strconv.ParseInt(ports2[0], 10, 32)
	if err != nil {
		panic(err)
	}
	name1 := r.Form["name1"]
	type1 := r.Form["type"]
	namespace := r.Form["namespace"]
	app := r.Form["app"]
	tag := r.Form["tag"]
	svcnode := &v1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: name[0],
		},
		Spec: corev1.ServiceSpec{
			Ports: []corev1.ServicePort{
				{
					Name:     name1[0],
					Port:     int32(in),
					NodePort: int32(in2),
				},
			},
			Type: "NodePort",
			Selector: map[string]string{
				app[0]: tag[0],
			},
		},
	}
	svccluster := &v1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: name[0],
		},
		Spec: corev1.ServiceSpec{
			Ports: []corev1.ServicePort{
				{
					Name: name1[0],
					Port: int32(in),
				},
			},
			Type: "ClusterIP",
			Selector: map[string]string{
				app[0]: tag[0],
			},
		},
	}
	switch {
	case type1[0] == "NodePort":
		svcc, err := getlink().CoreV1().Services(namespace[0]).Create(context.Background(), svcnode, metav1.CreateOptions{})
		if err != nil {
			fmt.Fprint(w, err)
			panic(err)
		} else {

			fmt.Fprintf(w, "svc create success：%q \n", svcc.GetObjectMeta().GetName())
			fmt.Printf("svc create success：%q \n", svcc.GetObjectMeta().GetName())
		}
	case type1[0] == "ClusterIP":
		svcc, err := getlink().CoreV1().Services(namespace[0]).Create(context.Background(), svccluster, metav1.CreateOptions{})
		if err != nil {
			fmt.Fprint(w, err)
			panic(err)
		} else {
			fmt.Fprintf(w, "svc create success：%q \n", svcc.GetObjectMeta().GetName())
			fmt.Printf("svc create success：%q \n", svcc.GetObjectMeta().GetName())
		}
	default:
		svcc, err := getlink().CoreV1().Services(namespace[0]).Create(context.Background(), svcnode, metav1.CreateOptions{})
		if err != nil {
			fmt.Fprint(w, err)
			panic(err)
		} else {
			fmt.Fprintf(w, "svc create success：%q \n", svcc.GetObjectMeta().GetName())
			fmt.Printf("svc create success：%q \n", svcc.GetObjectMeta().GetName())
		}
	}
}

func deletepod(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	name := r.Form["name"]
	namespace := r.Form["namespace"]
	poddelete := getlink().CoreV1().Pods(namespace[0]).Delete(context.Background(), name[0], metav1.DeleteOptions{})
	fmt.Fprintf(w, "delete pod succcss %+v\n", poddelete)
	fmt.Printf("delete pod succcss %+v\n", poddelete)
}

func deletesvc(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	name := r.Form["name"]
	namespce := r.Form["namespace"]
	svcdelete := getlink().CoreV1().Services(namespce[0]).Delete(context.Background(), name[0], metav1.DeleteOptions{})
	fmt.Printf("delete pod succcss %+v\n", svcdelete)
	fmt.Fprintf(w, "delete pod succcss %+v\n", svcdelete)
}

func getpodinfo(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	w.Header().Set("Access-Control-Allow-Origin", "*")
	fmt.Println("NameSpace:", r.Form["namespace"])
	nss := r.Form["namespace"]
	fmt.Println("Name:", r.Form["name"])
	names := r.Form["name"]
	podl, err := getlink().CoreV1().Pods(nss[0]).Get(context.Background(), names[0], metav1.GetOptions{})
	if err != nil {
		fmt.Fprint(w, false)
		//panic(err)
	} else {
		b, err := json.Marshal(podl)
		if err != nil {
			panic(err)
		}
		s := string(b)
		fmt.Fprint(w, s)
	}

}

func getpodquantity(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	pods, err := getlink().CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("%d", len(pods.Items))
	fmt.Fprint(w, len(pods.Items))
}
func getsvcquantity(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	svcs, err := getlink().CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("%d", len(svcs.Items))
	fmt.Fprint(w, len(svcs.Items))
}

func getpodstatus(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	r.ParseForm()
	w.Header().Set("Content-Type", "application/json")
	//w.Write([]byte("{}"))
	pods, err := getlink().CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	var pd Pddss
	for _, pod := range pods.Items {
		name := pod.ObjectMeta.Name
		status := string(pod.Status.Phase)
		namespace := pod.ObjectMeta.Namespace
		pd.Pdds = append(pd.Pdds, Pdd{
			Name:              name,
			Status:            status,
			CreationTimestamp: pod.ObjectMeta.CreationTimestamp,
			Namespace:         namespace,
		})
		fmt.Printf("Name: %s, Status: %s, CreateTime: %s,Namespace: %s \n", pod.ObjectMeta.Name, pod.Status.Phase, pod.ObjectMeta.CreationTimestamp, pod.ObjectMeta.Namespace)
	}
	b, err := json.Marshal(pd)
	if err != nil {
		panic(err)
	}
	fmt.Fprint(w, string(b))
}

type Pdd struct {
	Name              string
	Status            string
	CreationTimestamp metav1.Time
	Namespace         string
}

type Pddss struct {
	Pdds []Pdd
}

func main() {
	http.HandleFunc("/getsvcinfo", getsvcinfo)
	http.HandleFunc("/getpodinfo", getpodinfo)
	http.HandleFunc("/createpod", createpod)
	http.HandleFunc("/createsvc", createsvc)
	http.HandleFunc("/deletepod", deletepod)
	http.HandleFunc("/deletesvc", deletesvc)
	http.HandleFunc("/getpodquantity", getpodquantity)
	http.HandleFunc("/getsvcquantity", getsvcquantity)
	http.HandleFunc("/getpodstatus", getpodstatus)
	err := http.ListenAndServe(":9090", nil) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
